package com.wiscamp.ninechapters.threeparties.alipay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.wiscamp.ninechapters.threeparties.alipay.AlipayOrder;
import com.wiscamp.ninechapters.threeparties.alipay.config.AlipayConfig;
import com.wiscamp.ninechapters.threeparties.alipay.entity.AlipayPreOrderParams;
import com.wiscamp.ninechapters.threeparties.alipay.entity.RefundRequestParams;
import com.wiscamp.ninechapters.threeparties.alipay.entity.qrcode.*;
import com.wiscamp.ninechapters.threeparties.alipay.service.AlipayService;
import com.wiscamp.ninechapters.threeparties.alipay.utils.ParamsUtil;
import cube.ddd.aspect.HandleServiceException;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Service
public class AlipayServiceImpl implements AlipayService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private AlipayConfig alipayConfig;

    //@Autowired
    //private PaymentsService paymentsService;

    /**
     * 通用的退款接口
     *
     * @param requestParams
     * @return
     */
    @Override
    public RefundResponse pcRefund(RefundRequestParams requestParams) {
        AlipayClient alipayClient = getAlipayClient();
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        request.setBizContent(JSON.toJSONString(requestParams));
        AlipayTradeRefundResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        if (response.isSuccess()) {
            RefundResponseSign refundResponseSign = JSON.parseObject(response.getBody(), RefundResponseSign.class);
            return refundResponseSign.getAlipay_trade_refund_response();
        }
        return null;
    }

    /**
     * 扫码运行代码
     * 验签通过返回QrResponse
     * 失败打印日志信息
     *
     * @param model
     * @return
     */
    @Override
    public QrCodeResponse qrcodePay(AlipayTradePrecreateModel model) {
        AlipayClient alipayClient = getAlipayClient();
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setBizModel(model);
        request.setNotifyUrl(alipayConfig.getNotify_url());
        AlipayTradePrecreateResponse alipayTradePrecreateResponse = null;
        try {
            alipayTradePrecreateResponse = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        QrResponse qrResponse = JSON.parseObject(alipayTradePrecreateResponse.getBody(), QrResponse.class);
        return qrResponse.getAlipay_trade_precreate_response();
    }

    /**
     * 扫码支付的回调
     *
     * @param request
     * @return
     */
    @Override
    public QrServiceEntity alipayNotify(HttpServletRequest request) {
        logger.debug("阿里支付宝notify调用。");
        Map<String, String> map = ParamsUtil.paramsToMap(request);
        QrServiceEntity qrServiceEntity = new QrServiceEntity();
        qrServiceEntity.setReceived(false);
        for (String key : map.keySet()) {
            System.out.println("[ " + key + " = " + map.get(key) + " ]");
            logger.debug("[ " + key + " = " + map.get(key) + " ]");
        }
        try {
            boolean flag = AlipaySignature.rsaCheckV1(map, alipayConfig.getAlipay_public_key(), alipayConfig.getCharset(),
                    alipayConfig.getSign_type());
            String json = JSON.toJSONString(map);
            logger.info("Alipay notify===>" + json);
            if (flag) {
                qrServiceEntity.setTransactionStatus(map.get("trade_status"));

                //商户订单号
                /*String out_trade_no = map.get("out_trade_no");
                long orderId = Long.parseLong(out_trade_no);
                var payment = paymentsService.getOrderPayment(orderId);
                if (payment != null) {
                    payment.setNotifyTime(LocalDateTime.now());
                    paymentsService.updateOrderPayment(payment);
                }*/
                return qrServiceEntity;
            } else {
                return qrServiceEntity;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return qrServiceEntity;
        }
    }

    /**
     * 退款查询接口
     *
     * @param refundQueryParams
     * @return
     */
    @Override
    public RefundQueryResponse refundQuery(RefundQueryParams refundQueryParams) {
        AlipayClient alipayClient = getAlipayClient();
        AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
        request.setBizContent(JSON.toJSONString(refundQueryParams));
        AlipayTradeFastpayRefundQueryResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        RefundQueryResponseSign refundQueryResponseSign = JSON.parseObject(response.getBody(), RefundQueryResponseSign.class);
        if (response.isSuccess()) {
            return refundQueryResponseSign.getAlipay_trade_fastpay_refund_query_response();
        } else {//订单不存在执行

        }
        return null;
    }

    @Override
    @HandleServiceException
    public String pcPreOrder(AlipayPreOrderParams alipayPreOrderParams) {
        logger.debug("阿里支付宝下单调用。");

        double amount = Double.parseDouble(alipayPreOrderParams.getTotal_amount());
        //var orderPayment = paymentsService.createOrderPayment(alipayPreOrderParams.getUserId(), "ALIPAY", "", alipayPreOrderParams.getGoodsCode(), amount);

        AlipayClient alipayClient = getAlipayClient();
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
        alipayRequest.setReturnUrl(alipayConfig.return_url);
        alipayRequest.setNotifyUrl(alipayConfig.notify_url);
        //官网支付固定值
        PreOrderParams preOrderParams = new PreOrderParams();
        preOrderParams.setSubject(alipayPreOrderParams.getGoodsCode() + "模拟考试码");
        preOrderParams.setBody(preOrderParams.getSubject() + " 请访问 contest.wiscamp.com 注册登录后使用此模考码进行模考");
        //preOrderParams.setOut_trade_no(String.valueOf(orderPayment.getOrderId()));
        preOrderParams.setProduct_code("FAST_INSTANT_TRADE_PAY");
        preOrderParams.setTotal_amount(alipayPreOrderParams.getTotal_amount());

        var parameterJson = JSON.toJSONString(preOrderParams);
        alipayRequest.setBizContent(parameterJson);
        logger.debug(parameterJson);
        String form = "";
        try {
            var alipayResponse = alipayClient.pageExecute(alipayRequest);
            form = alipayResponse.getBody(); //调用SDK生成表单
            // String tradeNo = alipayResponse.getOutTradeNo();

        } catch (AlipayApiException e) {
            logger.error("支付宝PC支付下单异常:" + e.getErrMsg());
            e.printStackTrace();
        }
        logger.debug(form);
        return form;
    }

    @HandleServiceException
    public AlipayOrder alipayReturn(HttpServletRequest request) {
        logger.debug("阿里支付宝return调用。");
        //获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        try {
            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.alipay_public_key, alipayConfig.charset, alipayConfig.sign_type); //调用SDK验证签名
            //——请在这里编写您的程序（以下代码仅作参考）——
            if (signVerified) {
                AlipayOrder alipayOrder = new AlipayOrder();
                //商户订单号
                String out_trade_no = request.getParameter("out_trade_no");
                alipayOrder.setOutTradeNo(out_trade_no);

                long orderId = Long.parseLong(out_trade_no);
                alipayOrder.setOrderId(orderId);

                //支付宝交易号
                String trade_no = request.getParameter("trade_no");
                alipayOrder.setTradeNo(trade_no);

                //付款金额
                String total_amount = request.getParameter("total_amount");
                double amount = Double.parseDouble(total_amount);
                alipayOrder.setAmount(amount);
                return alipayOrder;

                /*var payment = paymentsService.getOrderPayment(orderId);
                if (payment == null)
                    ExceptionHandler.throwServiceException(null, logger, "NOT_FOUND_ORDERPAYMENT", null);
                payment.setPayTime(LocalDateTime.now());
                String examCode = assessmentService.generateAssessmentCodeForUser(payment.getUserId(), payment.getGoodsCode());
                payment.setAssessmentCode(examCode);
                payment.setTransactionNumber(trade_no);
                payment.setAmount(amount);
                paymentsService.updateOrderPayment(payment);
                logger.debug("trade_no:"+trade_no+"<br/>out_trade_no:"+out_trade_no+"<br/>total_amount:"+total_amount);
                return examCode;*/
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage());
        }
        return null;
    }

    /**
     * 获取AlipayClient对象
     *
     * @return
     */
    private AlipayClient getAlipayClient() {
        AlipayClient alipayClient =
                new DefaultAlipayClient(alipayConfig.getGatewayUrl(), alipayConfig.getApp_id(), alipayConfig.getMerchant_private_key(),
                        "JSON", alipayConfig.getCharset(), alipayConfig.getAlipay_public_key(), alipayConfig.getSign_type()); //获得初始化的AlipayClient

        return alipayClient;
    }
}
